package fmse.uaic.k.configuration_abstraction.abstract_classes;

import java.util.List;

import fmse.uaic.k.configuration_abstraction.abstract_visitor.KAbstractNodeVisitor;
import fmse.uaic.k.configuration_abstraction.visitors.PrintVisitor;

public abstract class KAbstractTree {
	protected KAbstractNode root;

	public void dfs(KAbstractNodeVisitor abstractVisitor) {
		dfs(root, abstractVisitor);
	}

	/**
	 * Depth First Search Algorithm
	 * 
	 * @param abstractNode
	 * @param abstractVisitor
	 */
	private void dfs(KAbstractNode abstractNode,
			KAbstractNodeVisitor abstractVisitor) {
		abstractVisitor.visit(abstractNode);

		List<KAbstractNode> children = abstractNode.getChildren();

		if (children != null)
			for (KAbstractNode child : children) {
				dfs(child, abstractVisitor);
			}
	}

	@Override
	public String toString() {
		PrintVisitor printer = new PrintVisitor();
		dfs(root, printer);
		return "TREE: " + printer.getPrinter() + ";";
	}

	public void print() {
		print(root, "");
	}

	private void print(KAbstractNode root, String indent) {
		if (root == null)
			return;

		if (root.children == null || root.children.size() == 0)
			System.out.print(indent + "<" + root.label + ">");
		else
			System.out.println(indent + "<" + root.label + ">");

		if (root.children != null) {
			for (KAbstractNode ch : root.children) {
				print(ch, indent + "  ");
			}

		}
		if (root.children == null || root.children.size() == 0)
			System.out.println("</" + root.label + ">");
		else
			System.out.println(indent + "</" + root.label + ">");

	}

}
